package app

import (
	"context"

	"github.com/glennliao/apijson-go"
	"github.com/glennliao/apijson-go/action"
	"github.com/glennliao/apijson-go/util"
	"github.com/gogf/gf/v2/errors/gcode"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/util/gconv"
)

func 初始化钩子(api实例 *apijson.APIJSON) {

	api实例.Z注册动作钩子(action.G钩子{
		S适用场景: []string{"Note"},
		C处理程序: nil,
		S事务内处理程序: func(上下文 context.Context, 请求 *action.G钩子请求) error {
			用户, _ := 上下文.Value(用户ID键).(*当前用户)
			for 索引 := range 请求.J节点.S数据 {
				请求.J节点.S数据[索引]["group_id"] = 用户.用户ID
			}

			错误 := 请求.X下一个()

			for 索引 := range 请求.J节点.S数据 {

				笔记ID := 请求.J节点.S数据[索引]["note_id"]
				if 请求.S是否为Put请求() {
					笔记ID = 请求.J节点.T条件[索引]["note_id"]
				}

				_, 错误 = g.Model("note_history").Ctx(上下文).Insert(g.Map{
					"note_id":    笔记ID,
					"content":    请求.J节点.S数据[索引]["content"],
					"created_by": 用户.用户ID,
					"is_public":  请求.J节点.S数据[索引]["is_public"],
					"encode_key": 请求.J节点.S数据[索引]["encode_key"],
				})
				if 错误 != nil {
					return 错误
				}
			}

			return 错误
		},
	})

	api实例.Z注册动作钩子(action.G钩子{
		S适用场景: []string{"Config"},
		S事务内处理程序: func(上下文 context.Context, 请求 *action.G钩子请求) error {
			用户, _ := 上下文.Value(用户ID键).(*当前用户)

			for 索引 := range 请求.J节点.S数据 {

				配置键 := 请求.J节点.S数据[索引]["key"]

				记录, 错误 := g.Model("config").Ctx(上下文).One(g.Map{
					"for_id": 用户.用户ID,
					"key":    配置键,
					"for":    "user",
				})
				if 错误 != nil {
					return 错误
				}

				if 记录.IsEmpty() {
					g.Model("config").Ctx(上下文).Insert(g.Map{
						"for":    "user",
						"for_id": 用户.用户ID,
						"key":    配置键,
					})
				}
			}

			错误 := 请求.X下一个()
			return 错误
		},
	})

	api实例.Z注册动作钩子(action.G钩子{
		S适用场景: []string{"*"},
		C处理程序: nil,
		S事务内处理程序: func(上下文 context.Context, 请求 *action.G钩子请求) error {
			用户, 存在 := 上下文.Value(用户ID键).(*当前用户)
			if 存在 {
				for 索引 := range 请求.J节点.S数据 {
					if 请求.S是否为Post请求() || 请求.S是否为Put请求() {
						请求.J节点.S数据[索引]["updated_by"] = 用户.用户ID
						if 请求.S是否为Post请求() {
							请求.J节点.S数据[索引]["created_by"] = 用户.用户ID
						}
					}
				}
			}

			if 请求.S是否为Delete请求() {
				if 请求.J节点.J键名 == 表书签分类 {
					for _, 条件 := range 请求.J节点.T条件 {
						分类ID := 条件["cate_id"]

						记录, 错误 := g.DB().Model("bookmark_cate").Where("parent_id", 分类ID).Safe().Ctx(上下文).One()
						if 错误 != nil {
							return 错误
						}

						if !记录.IsEmpty() {
							return gerror.NewCodef(gcode.CodeInvalidParameter, "分类下有子分类，不能删除，cate_id: %v", 分类ID)
						}

						记录, 错误 = g.DB().Model("bookmark").Where("cate_id", 分类ID).Safe().Ctx(上下文).One()
						if 错误 != nil {
							return 错误
						}

						if !记录.IsEmpty() {
							return gerror.NewCodef(gcode.CodeInvalidParameter, "分类下有书签，不能删除，cate_id: %v", 分类ID)
						}
					}
				}
			}

			if 请求.S是否为Put请求() && 请求.J节点.J键名 == 表书签使用 {

				for 索引 := range 请求.J节点.T条件 {
					请求.J节点.T条件[索引]["bm_id"] = 请求.J节点.S数据[索引]["bm_id"]
				}
			}

			错误 := 请求.X下一个()

			if 请求.S是否为Put请求() && 请求.J节点.J键名 == 表书签使用 {
				if gconv.Int64(请求.J节点.F返回值["count"]) == 0 {
					模型 := g.DB().Model("bookmark_use").Safe().Ctx(上下文)

					用户, _ := 上下文.Value(用户ID键).(*当前用户)
					模型.Insert(g.Map{
						"times":   "1",
						"bm_id":   util.Z转字符串(请求.J节点.T条件[0]["bm_id"]),
						"user_id": 用户.用户ID,
					})
				}
			}
			return 错误
		},
	})

}
